package com.meshnetics.gb.stack.mac.primitives;

import com.meshnetics.gb.stack.core.event.StackEventType;
import com.meshnetics.gb.stack.core.event.StackRequest;
import com.meshnetics.gb.stack.mac.RadioMACStackLayer;
import com.meshnetics.gb.type.impl.ByteUtils;
import com.meshnetics.gb.type.impl.zcl.Bool;
import com.meshnetics.gb.type.impl.zcl.TypeBool;
import com.meshnetics.gb.type.impl.zcl.TypeUInt;
import com.meshnetics.gb.type.impl.zcl.UInt;

import java.nio.ByteBuffer;

/**
 * WRITE DESCRIPTION HERE
 *
 * @author AKovylin
 */
public class MACSyncRequest extends StackRequest implements MACCommand {
    public static final byte CODE = 0x5f;

    private final UInt logicalChannel;
    private final Bool trackBeacon;

    public MACSyncRequest(int logicalChannel, boolean trackBeacon) {
        this((byte) (logicalChannel & 0xff), trackBeacon);
    }

    public MACSyncRequest(byte logicalChannel, boolean trackBeacon) {
        this(new Byte(logicalChannel), Boolean.valueOf(trackBeacon));
    }

    public MACSyncRequest(Byte logicalChannel, Boolean trackBeacon) {
        this((UInt) TypeUInt.UINT_8.fromObject(logicalChannel), (Bool) TypeBool.BOOLEAN.fromObject(trackBeacon));
    }

    public MACSyncRequest(UInt logicalChannel, Bool trackBeacon) {
        super("macSyncRequest", StackEventType.LME_TYPE);
        if (logicalChannel == null) {
            throw new NullPointerException("logicalChannel is null");
        }
        if (trackBeacon == null) {
            throw new NullPointerException("trackBeacon is null");
        }
        int check = ((Number) logicalChannel.toObject()).intValue();
        if (check < 0 || check > 0x1a) {
            throw new IllegalArgumentException("invalid logicalChannel, must be in rangle 0x00-0x1a");
        }
        if (trackBeacon.isInvalid()) {
            throw new IllegalArgumentException("invalid trackBeacon");
        }
        this.logicalChannel = logicalChannel.convert(TypeUInt.UINT_8);
        this.trackBeacon = trackBeacon;
    }

    public UInt getLogicalChannelType() {
        return logicalChannel;
    }

    public Bool getTrackBeaconType() {
        return trackBeacon;
    }

    public Byte getLogicalChannel() {
        return (Byte) logicalChannel.toObject();
    }

    public Boolean getTrackBeacon() {
        return (Boolean) trackBeacon.toObject();
    }

    public byte getCode() {
        return CODE;
    }

    public int getSize(RadioMACStackLayer layer) {
        return 2;
    }

    public void serialize(ByteBuffer bb, RadioMACStackLayer layer) {
        ByteUtils.ensureNotNull(bb);
        logicalChannel.serialize(bb);
        trackBeacon.serialize(bb);
    }

    public String toString() {
        return getName() + '(' + logicalChannel + ',' + trackBeacon + ')';
    }
}
